package com.xyy.saas.payment.callback.core.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jddglobal.open.client.DefaultSpiJddClient;
import com.xyy.saas.payment.adpater.jd.common.JDConstants;
import com.xyy.saas.payment.adpater.jdCredit.req.CreditResultNotifyReq;
import com.xyy.saas.payment.adpater.jdCredit.support.JdCreditClientFactory;
import com.xyy.saas.payment.callback.core.dto.CallbackMsg;
import com.xyy.saas.payment.callback.core.result.CallbackRunner;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.PinganLoanApplyStatusEnum;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.cores.vo.PinganLoanNotifyApplyStatusVo;
import com.xyy.saas.payment.dao.model.PayFinanceApply;
import com.xyy.saas.payment.service.PinganLoanFinanceApplyService;
import com.xyy.saas.payment.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 京东融资采购准入结果通知handler
 */
@Component
@Slf4j
public class JdCreditContractCallBackHandler {
    @Resource
    private PinganLoanFinanceApplyService pinganLoanFinanceApplyService;
    @Autowired
    private CallbackRunner callbackRunner;
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private LeafUtil leafUtil;
    public String callBackHandler(HttpServletRequest req) throws Exception {
        DefaultSpiJddClient defaultSpiJddClient = JdCreditClientFactory.getDefaultSpiJddClient();
        String bizContent = defaultSpiJddClient.receive(req);
        log.info("JdCreditContractCallBackHandler bizContent={}", bizContent);
        CreditResultNotifyReq creditResultNotifyReq = JSON.parseObject(bizContent, CreditResultNotifyReq.class);
        log.info("creditResultNotifyReq:{}", JSONObject.toJSONString(creditResultNotifyReq));
        if (StringUtils.isEmpty(creditResultNotifyReq.getContractNo())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }
        String key = RedisUtil.JD_CREDIT_RESULT_NOTIFY + creditResultNotifyReq.getBizNo();
        if(!redisUtil.setNx(key,"1",10)) {
            throw new PaymentException(ResultCodeEnum.PROFIT_SHARING_REPEAT_REQUEST);
        }

        PayFinanceApply payFinanceApply = null;
        // 如果客户线下自己去京东申请，这里个bizNo为空
        if (StringUtils.isNotEmpty(creditResultNotifyReq.getBizNo())) {
            payFinanceApply = pinganLoanFinanceApplyService.selectByThirdApplyNo(creditResultNotifyReq.getBizNo());
        }

        // 没有查到的默认取客户下最新的一条
        String custCode = creditResultNotifyReq.getExt() == null ? null : creditResultNotifyReq.getExt().get("custCode").toString();
        if (payFinanceApply == null) {
            payFinanceApply = pinganLoanFinanceApplyService.findLatestRecord(custCode, 2);
            // 通过denyReason区分通知的场景
            if (payFinanceApply != null) {
                payFinanceApply.setDenyReason("bizNo" + creditResultNotifyReq.getBizNo() + payFinanceApply.getDenyReason());
            }
        }
        // 没有申请记录，手动插入一条
        if (payFinanceApply == null) {
            String thirdApplyNo = leafUtil.getSnowflakeId();
            PayFinanceApply record = new PayFinanceApply();
            record.setThirdApplyNo(thirdApplyNo);
            record.setFinanceChannel(2);
            record.setBusinessUserId(custCode);
            record.setBusinessUserName("");
            record.setBusinessType(custCode);
            record.setApplyStatus(PinganLoanApplyStatusEnum.UN_PRE_APPLY.getCode());
            record.setCreateTime(new Date());
            record.setUpdateTime(new Date());
            record.setDenyReason("回调时手动补记录");
            pinganLoanFinanceApplyService.insert(record);
            payFinanceApply = record;
        }

        // 落库
        if (creditResultNotifyReq.getResCode().equals("0000000")) {
            payFinanceApply.setContractNo(creditResultNotifyReq.getContractNo());
            payFinanceApply.setApplyStatus(PinganLoanApplyStatusEnum.SIGNED_CONT_SUCCESS.getCode());
            payFinanceApply.setAmountStartDate(creditResultNotifyReq.getAuditDate().substring(0,8));
            payFinanceApply.setAmountEndDate(creditResultNotifyReq.getCreditEndDate().substring(0,8));
            payFinanceApply.setApproveAmount(AmountCastUtil.formatBigDecimal2PercentInt(creditResultNotifyReq.getCreditLimit())); // 授信额度(单位分) 单位：分，已签署合同成功时返回
            payFinanceApply.setDenyReason(creditResultNotifyReq.getResDesc() + payFinanceApply.getDenyReason());
            payFinanceApply.setDayRate((String) creditResultNotifyReq.getExt().get("dayRate"));
        } else {
            // 如果是提额 or续约授信 失败的情况下不处理
            Object accessType = creditResultNotifyReq.getExt() == null ? null : creditResultNotifyReq.getExt().get("accessType");
            if ("CREDIT_EXPIRED".equals(accessType) || "INCREASE_LIMIT".equals(accessType)) {
                return "";
            }
            payFinanceApply.setDenyReason(creditResultNotifyReq.getResDesc() + payFinanceApply.getDenyReason());
            payFinanceApply.setApplyStatus(PinganLoanApplyStatusEnum.SIGN_FAILED.getCode());
        }

        log.info("creditResultNotifyReq update {}",JSONObject.toJSONString(payFinanceApply));
        pinganLoanFinanceApplyService.updateByPrimaryKeySelective(payFinanceApply);

        // 回调EC
        CallbackMsg callbackMsg = new CallbackMsg();
        callbackMsg.setCallback(JDConstants.JD_CREDIT_CALLBACK);
        callbackMsg.setType("applyStatus");
        callbackMsg.setMsg(creditResultNotifyReq.getResDesc());
        callbackMsg.setExtend(JSON.toJSONString(po2Vo(payFinanceApply)));

        callbackRunner.callback(callbackMsg);
        return "";
    }

    public String callBack(CreditResultNotifyReq creditResultNotifyReq) throws Exception {
        log.info("creditResultNotifyReq2:{}", JSONObject.toJSONString(creditResultNotifyReq));
        if (!creditResultNotifyReq.checkParam()) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }
        String key = RedisUtil.JD_CREDIT_RESULT_NOTIFY + creditResultNotifyReq.getBizNo();
        if(!redisUtil.setNx(key,"1",10)) {
            throw new PaymentException(ResultCodeEnum.PROFIT_SHARING_REPEAT_REQUEST);
        }
//        CreditResultNotifyReq creditResultNotifyReq = new CreditResultNotifyReq();
//        creditResultNotifyReq.setReqNo("20240618013645285");
//        creditResultNotifyReq.setReqDate("20240617200730");
//        creditResultNotifyReq.setResCode("0000000");
//        creditResultNotifyReq.setResDesc("准入成功");
//        creditResultNotifyReq.setBizNo("1718620688797");
//        creditResultNotifyReq.setContractNo("A2024061701001009");
//        creditResultNotifyReq.setCreditLimit(new BigDecimal("2000000.0000"));
//        creditResultNotifyReq.setRemainLimit(new BigDecimal("526805.4300"));
//        creditResultNotifyReq.setCreditEndDate("20250117000000");
//        creditResultNotifyReq.setAuditDate("20240617200730");
//        Map et = new HashMap();
//        et.put("dayRate","0.0001923611");
//        creditResultNotifyReq.setExt(et);


        PayFinanceApply payFinanceApply = pinganLoanFinanceApplyService.selectByThirdApplyNo(creditResultNotifyReq.getBizNo());
        if (payFinanceApply == null || PinganLoanApplyStatusEnum.SIGNED_CONT_SUCCESS.getCode().equals(payFinanceApply.getApplyStatus())) {
            return "";
        }
        // 落库
        if (creditResultNotifyReq.getResCode().equals("0000000")) {
            payFinanceApply.setContractNo(creditResultNotifyReq.getContractNo());
            payFinanceApply.setApplyStatus(PinganLoanApplyStatusEnum.SIGNED_CONT_SUCCESS.getCode());
            payFinanceApply.setAmountStartDate(creditResultNotifyReq.getAuditDate().substring(0,8));
            payFinanceApply.setAmountEndDate(creditResultNotifyReq.getCreditEndDate().substring(0,8));
            payFinanceApply.setApproveAmount(AmountCastUtil.formatBigDecimal2PercentInt(creditResultNotifyReq.getCreditLimit())); // 授信额度(单位分) 单位：分，已签署合同成功时返回
            payFinanceApply.setDenyReason(creditResultNotifyReq.getResDesc());
            payFinanceApply.setDayRate((String) creditResultNotifyReq.getExt().get("dayRate"));
        } else {
            payFinanceApply.setDenyReason(creditResultNotifyReq.getResDesc());
            payFinanceApply.setApplyStatus(PinganLoanApplyStatusEnum.SIGN_FAILED.getCode());

        }

        log.info("creditResultNotifyReq update {}",JSONObject.toJSONString(payFinanceApply));
        pinganLoanFinanceApplyService.updateByPrimaryKeySelective(payFinanceApply);

        // 回调EC
        CallbackMsg callbackMsg = new CallbackMsg();
        callbackMsg.setCallback(JDConstants.JD_CREDIT_CALLBACK);
        callbackMsg.setType("applyStatus");
        callbackMsg.setMsg(creditResultNotifyReq.getResDesc());
        callbackMsg.setExtend(JSON.toJSONString(po2Vo(payFinanceApply)));

        callbackRunner.callback(callbackMsg);
        return "";
    }

    private PinganLoanNotifyApplyStatusVo po2Vo(PayFinanceApply payFinanceApply) {
        PinganLoanNotifyApplyStatusVo notifyApplyStatusVo = new PinganLoanNotifyApplyStatusVo();
        notifyApplyStatusVo.setThirdApplyNo(payFinanceApply.getThirdApplyNo());
        notifyApplyStatusVo.setUserId(payFinanceApply.getBusinessUserId());
        notifyApplyStatusVo.setContractNo(payFinanceApply.getContractNo());
        notifyApplyStatusVo.setApplyStatus(PinganLoanApplyStatusEnum.getEnum(payFinanceApply.getApplyStatus()));
        notifyApplyStatusVo.setAmountStartdate(payFinanceApply.getAmountEndDate());
        notifyApplyStatusVo.setAmountEnddate(payFinanceApply.getAmountEndDate());
        notifyApplyStatusVo.setApproveAmount(payFinanceApply.getApproveAmount());
        notifyApplyStatusVo.setDenyReason(payFinanceApply.getDenyReason());
        notifyApplyStatusVo.setDayRate(payFinanceApply.getDayRate());
        return notifyApplyStatusVo;
    }

}
